package sc.server;

import java.io.IOException;

import sc.datainterchange.CodedInputBuffer;
import sc.nio.NioChannelData;
import sc.nio.NioHandler;

/**
 * Client listening thread class.
 * 
 * @author stephencarmody@gmail.com Stephen Carmody
 */
public final class ClientHandler extends NioHandler
{
	// Coded data buffer received from client
	private final CodedInputBuffer codedinput = new CodedInputBuffer();
	
	// Instance of Client associated with communication
	private Client client = null;
	
	/**
	 * Creates an instance of RequestHandler.
	 */
	public ClientHandler()
	{
	}
	
	/**
	 * Called when a SocketChannel with data is available to read.
	 * 
	 * @param channeldata
	 * 			An NioChannelData instance
	 * @throws IOException 
	 */
	protected void read(NioChannelData channeldata)
	{
		int tag;
		
		this.codedinput.put(channeldata.buffer);
		
		String name;
		try
		{
			name = this.codedinput.readString();
			client = Client.getClient(name);

			while ((tag = this.codedinput.readTag()) != 0)
			{
				switch (tag)
				{
				case Protocol.GET:
					readGet();
					break;
				case Protocol.AUTHENTICATE:
					readAuthenticate();
					break;
				case Protocol.CONNECT:
					readConnect();
					break;
				}
			}
			
			client.flush(channeldata.channel);
		}
		catch (Exception e)
		{
			Server.logger.warning(e.getMessage());
		}
	}
	
	/**
	 * Connection request, for now just ask client to authenticate.
	 * 
	 * @throws IOException 
	 */
	private void readConnect() throws IOException
	{
		client.writeAuthenticate();
	}
	
	/**
	 * Authenticates the client requesting authentication.
	 * 
	 * @throws IOException 
	 */
	private void readAuthenticate() throws IOException
	{
		String password = this.codedinput.readString();
		Server.logger.info("Connection accepted for " + client.getName());
		client.writeAuthenticated();
		client.writeObject(client.getAvatar().getID());
	}

	/**
	 * Called when a client asked for a specific Container.
	 * 
	 * @throws IOException 
	 */
	private void readGet() throws IOException
	{
		int id = this.codedinput.readInt32();
		client.writeObject(id);
	}
	
	/**
	 * Sends tiles to the client in a spiralling outwards fashion from the
	 * Avatars current containing Tile.
	 * 
	 * @param avatar
	 * 			The players Avatar
	 *
	private void areaGet(Avatar avatar)
	{
		Tile tile = avatar.getTile();
		int tilex = tile.getTileX();
		int tilez = tile.getTileZ();
		int dx = 0;
		int dz = 0;
		int dn;
		int length = 1;
		int side = 0;		
		
		for (int distance = 0; distance < Server.VISIBILITY; distance++)
		{
			// Send Tiles along the current side of the spiral
			while (--length > 0)
			{
				
			}
			
			// Update the direction
			dn = -dz;
			dz = dx;
			dx = dn;
			
		}
	}*/
}
